package hsmgpslogger.client;

import hsmgpslogger.shared.PositionInfo;
import hsmgpslogger.shared.PositioningService;
import hsmgpslogger.shared.PositioningServiceAsync;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.MapType;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.Maps;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Hsmgpslogger implements EntryPoint {

	private int MAX_HIRES_MARKERS  = 10;
	private int MAX_MEDRES_MARKERS = 10;

	private int LORES_SHOWS_COUNT  = 10;
	private int MEDRES_SHOWS_COUNT = 10;
	
	HashMap<PositionInfo, Marker> hiResMarkers  = new HashMap<PositionInfo, Marker>();
	HashMap<PositionInfo, Marker> medResMarkers = new HashMap<PositionInfo, Marker>();
	HashMap<PositionInfo, Marker> loResMarkers  = new HashMap<PositionInfo, Marker>();
	
	boolean loResMarkersModified  = false;
	boolean medResMarkersModified = false;
	boolean hiResMarkersModified  = false;
	
	
	PositioningServiceAsync ps    = GWT.create(PositioningService.class);
	LinkedList<PositionInfo> trace = new LinkedList<PositionInfo>();
	
	MapWidget map = null;
	
	
	final Button sendButton = new Button("Read points");
	final Label status = new Label("ok");
	final HorizontalPanel hPanel = new HorizontalPanel(); 
	final VerticalPanel container = new VerticalPanel();
	final VerticalPanel pointsContainer = new VerticalPanel();
	

	public void onModuleLoad() {
		Maps.loadMapsApi("ABQIAAAAz7IEuuXQYqnrIQ-S_pTv_xRbJToLN5R4FUtbKIcbyYJlmE7ivxRAX3Sy6S3G_2tKWV0ZRapYlVt7JA", "2", false, new Runnable() {
			public void run() {
				biuldUI();
			}
		});
	}

	private void biuldUI() {
		LatLng kiev = LatLng.newInstance(50.422228,30.520779);
		map = new MapWidget(kiev, 5);
		
		map.setScrollWheelZoomEnabled(true);
		map.setCurrentMapType(MapType.getHybridMap());
		map.setSize("700px", "700px");
		map.addControl(new LargeMapControl());
		map.addOverlay(new Marker(kiev));

		container.setWidth("100%");
		container.setStyleName("controlsPanel");
		container.add(sendButton);
		container.add(pointsContainer);
		
		hPanel.add(map);
		hPanel.add(container);
		RootPanel.get("loggerContainer").add(hPanel);
		sendButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				readPoints();
			}
		});
	}

	private void readPoints() {
		ps.GetPositionInfo(1L, new AsyncCallback<List<PositionInfo>>() {
			@Override
			public void onFailure(Throwable caught) {
				status.setText("Fuck");
			}

			@Override
			public void onSuccess(List<PositionInfo> result) {
				status.setText("OK");
				pointsContainer.clear();
				for (PositionInfo pi : result) {
					trace.addFirst(pi);
				}
				redrawMarkers();
			}
		});
	}

	public void redrawMarkers(){
		HashMap<PositionInfo, Marker> hiResMarkersToDraw  = new HashMap<PositionInfo, Marker>();
		HashMap<PositionInfo, Marker> medResMarkersToDraw = new HashMap<PositionInfo, Marker>();
		HashMap<PositionInfo, Marker> loResMarkersToDraw  = new HashMap<PositionInfo, Marker>();
		

		int firstIndex = 0;
		int lastIndex  = 9;
		
		if (trace.size() < 10) 
			lastIndex = trace.size() - 1;
		
		for (int i = firstIndex; i < lastIndex; i++){
			PositionInfo pi = trace.get(i);
			hiResMarkersToDraw.put(pi , MarkerFactory.getHiResMarker(pi, map));
		}
		
		firstIndex = 10;
		lastIndex  = 90;
		
		if (trace.size() < 91)  
			lastIndex  = trace.size() - (trace.size() % 10);
		
		for (int i = firstIndex; i < lastIndex; i+=10){
			PositionInfo pi = trace.get(i);
			medResMarkersToDraw.put(pi , MarkerFactory.getMedResMarker(pi, map));
		}
		
		firstIndex = 100;
		lastIndex  = trace.size() - (trace.size() % 100);
		
		for (int i = firstIndex; i < lastIndex; i+=100){
			PositionInfo pi = trace.get(i);
			loResMarkersToDraw.put(pi , MarkerFactory.getLoResMarker(pi, map));
		}
		
		for (PositionInfo prev : hiResMarkers.keySet()){
			if (hiResMarkersToDraw.containsKey(prev))
				continue;
			map.removeOverlay(hiResMarkers.get(prev));
		}
		
		
//		Marker m = MarkerFactory.getHiResMarker(pi, map);
//		hiResMarkers.put(m, pi);
//		map.addOverlay(m);
	}
}
